#include "cpu/exec/template-start.h"

#define instr call

make_helper(concat(call_i_, SUFFIX)) {
	int len = concat(decode_i_, SUFFIX)(eip + 1);       //计算出指令长度
	reg_l(R_ESP) -= DATA_BYTE;                         //压栈
	MEM_W(reg_l(R_ESP), cpu.eip + len + 1);            //宏：向esp写入当前eip的下一个地址
	cpu.eip += (DATA_TYPE_S)op_src->val;				//更新eip到函数地址,这里的op_src->val是相对地址
	print_asm("call: 0x%x", cpu.eip + len + 1);
	return len + 1;
}

make_helper(concat(call_rm_, SUFFIX)) {
	int len = concat(decode_rm_, SUFFIX)(eip + 1);
	reg_l(R_ESP) -= DATA_BYTE;
	MEM_W(reg_l(R_ESP), cpu.eip + len + 1);
	cpu.eip = (DATA_TYPE_S)op_src->val - len - 1;
	print_asm("call: %s", op_src->str);
	return len + 1;
}

#include "cpu/exec/template-end.h"




/*               附个预编译结果

int call_i_l(swaddr_t eip) {
 int len = decode_i_l(eip + 1);
 (
     cpu.gpr[check_reg_index(R_ESP)]._32) -= 4;
     swaddr_write((cpu.gpr[check_reg_index(R_ESP)]._32), 4, cpu.eip + len + 1);
     cpu.eip += (int32_t)(&ops_decoded.src)->val;
     do { if(!(snprintf(assembly, 80, "call: 0x%x", cpu.eip + len + 1) < 80)) { fflush(stdout); fprintf(stderr, "\33[1;31m"); fprintf(stderr, "buffer overflow!"); fprintf(stderr, "\33[0m\n"); ((void) sizeof ((snprintf(assembly, 80, "call: 0x%x", cpu.eip + len + 1) < 80) ? 1 : 0), __extension__ ({ if (snprintf(assembly, 80, "call: 0x%x", cpu.eip + len + 1) < 80) ; else __assert_fail ("snprintf(assembly, 80, \"call: 0x%x\", cpu.eip + len + 1) < 80", "nemu/src/cpu/exec/control/call-template.h", 10, __extension__ __PRETTY_FUNCTION__); })); } } while(0);
     return len + 1;
}

int call_rm_l(swaddr_t eip) {
 int len = decode_rm_l(eip + 1);
(
     cpu.gpr[check_reg_index(R_ESP)]._32) -= 4;
     swaddr_write((cpu.gpr[check_reg_index(R_ESP)]._32), 4, cpu.eip + len + 1);
     cpu.eip = (int32_t)(&ops_decoded.src)->val - len - 1;
     do { if(!(snprintf(assembly, 80, "call: %s", (&ops_decoded.src)->str) < 80)) { fflush(stdout); fprintf(stderr, "\33[1;31m"); fprintf(stderr, "buffer overflow!"); fprintf(stderr, "\33[0m\n"); ((void) sizeof ((snprintf(assembly, 80, "call: %s", (&ops_decoded.src)->str) < 80) ? 1 : 0), __extension__ ({ if (snprintf(assembly, 80, "call: %s", (&ops_decoded.src)->str) < 80) ; else __assert_fail ("snprintf(assembly, 80, \"call: %s\", (&ops_decoded.src)->str) < 80", "nemu/src/cpu/exec/control/call-template.h", 19, __extension__ __PRETTY_FUNCTION__); })); } } while(0);
     return len + 1;
}


*/